import { message } from 'ant-design-vue';
import axios, { CreateAxiosDefaults } from 'axios'
import { IStandardResponse } from './base/index.type'
import { globalOptions } from '@/constants'
import { useUserStore } from '@/Store/userStore'
import router from '@/router'

message.config({
  maxCount: 1,
});

const refreshOptions: {
  pending: boolean
  queue: {
    resolve: (data: any) => void
    reject: (data: any) => void
    reqConfig: any
  }[]
} = {
  pending: false,
  queue: [],
}

export function genAxios(options: CreateAxiosDefaults) {
  const $http = axios.create(options)

  $http.interceptors.request.use(
    (originConifg) => {
      const reqConfig = {
        ...originConifg,
      }
      if (!reqConfig.url) console.error('Request url must not be null.')

      const method = String(reqConfig?.method).toUpperCase()
      if (method === 'POST') {
        if (!reqConfig.data) reqConfig.data = reqConfig.params || {}

        let hasFile = false

        Object.keys(reqConfig.data).forEach((key) => {
          typeof reqConfig.data[key] == 'object' && ((item) => (item instanceof FileList || item instanceof File || item instanceof Blob ? (hasFile = true) : 0))(reqConfig.data[key])
        })

        hasFile &&
          ((data) => {
            const formData = new FormData()
            Object.keys(data).forEach((key) => {
              formData.append('file', data[key])
            })

            reqConfig.data = formData
          })(reqConfig.data)
      }

      if (!refreshOptions.pending) {
        if (refreshOptions.queue.length > 0) {
          console.log('process queue', refreshOptions)
          refreshOptions.queue.forEach((item) => {
            $http(item.reqConfig).then(item.resolve).catch(item.reject)
          })

          refreshOptions.queue.length = 0
        }
      }
      
      const useStore = useUserStore();
      originConifg.headers['Authorization'] = useStore.token;

      return originConifg
    },
    (error) => {
      return Promise.reject(error)
    }
  )

  $http.interceptors.response.use(
    async (res: any) => {
      if(res.data?.code === 100){
        message.info('登录超时，请重新登录')
        router.push('/login');
        return;
      }
      return res.data
    },
    async (res) => {
      console.error(res)
      return res.response.data
    }
  )

  function post(url: string, data = {}, params = {}) {
    return $http({
      method: 'post',
      url,
      data,
      params,
    }) as Promise<IStandardResponse>
  }

  function get(url: string, params = {}) {
    return $http({
      method: 'GET',
      url,
      params,
    }) as Promise<IStandardResponse>
  }

  function put(url: string, data = {}, params = {}) {
    return $http({
      method: 'PUT',
      url,
      data,
      params,
    }) as Promise<IStandardResponse>
  }

  function del(url: string, data = {}, params = {}) {
    return $http({
      method: 'DELETE',
      url,
      data,
      params,
    }) as Promise<IStandardResponse>
  }

  function patch(url: string, data = {}, params = {}) {
    return $http({
      method: 'PATCH',
      url,
      data,
      params,
    }) as Promise<IStandardResponse>
  }

  return {
    $http,
    post,
    get,
    put,
    del,
    patch,
  }
}

export const endHttp =  genAxios({
  baseURL: `${globalOptions.getEndsUrl()}`,
})
